/**
 * @file boards\gd32f303cx\bsp\bsp_key.c
 *
 * bsp_key.c is not free software: you can not redistribute it and/or modify
 * it before obtaining permission from moorgen.
 *
 * This program is distributed in the hope that it will be useful
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 *
 * You should have received a copy of the license along with this program
 * from moorgen. If not, please contact us.
 *
 * @author HinsShum hinsshum@qq.com
 *
 * @encoding utf-8
 */

/*---------- includes ----------*/
#include "bsp_key.h"
#include "gd32f10x_libopt.h"
#include "options.h"
#include "gpio_group.h"

/*---------- macro ----------*/
#define s_rcu0 RCU_GPIOA
#define s_port0 GPIOA
#define s_pin1 GPIO_PIN_0
#define s_pin2 GPIO_PIN_1

#define s_rcu1 RCU_GPIOB
#define s_port1 GPIOB
#define s_pin3 GPIO_PIN_12
#define s_pin4 GPIO_PIN_5
#define s_pin5 GPIO_PIN_4
#define s_pin6 GPIO_PIN_13
/*---------- type define ----------*/
typedef enum {
    s1_id = 1,
    s2_id,
    s3_id,
    s4_id,
    s_id_null = 0xff,
} s_id;
/*---------- variable prototype ----------*/
/*---------- function prototype ----------*/
static bool bsp_init(void);
static void bsp_deinit(void);
static unsigned char bsp_get(unsigned char num);

/*---------- variable ----------*/
static gpio_group_describe_t key = {
    .group_name = "key",
    .ops.init = bsp_init,
    .ops.deinit = bsp_deinit,
    .ops.get = bsp_get,
    .ops.set = NULL,
    .group_num_max = DEV_KEY_NUM,
};
DEVICE_DEFINED(key, gpio_group, &key);

/*---------- function ----------*/
static bool bsp_init(void)
{
    rcu_periph_clock_enable(s_rcu0);
    rcu_periph_clock_enable(s_rcu1);
    gpio_init(s_port0, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, s_pin1 | s_pin2);
    gpio_init(s_port1, GPIO_MODE_IN_FLOATING, GPIO_OSPEED_50MHZ, s_pin3 | s_pin4 | s_pin5 | s_pin6);

    return true;
}

static void bsp_deinit(void)
{
    gpio_init(s_port0, GPIO_MODE_OUT_OD, GPIO_OSPEED_2MHZ, s_pin1 | s_pin2);
    gpio_init(s_port1, GPIO_MODE_OUT_OD, GPIO_OSPEED_2MHZ, s_pin3 | s_pin4 | s_pin5 | s_pin6);
}

static unsigned char bsp_get(unsigned char num) {
    if (s1_id == num)
        return gpio_input_bit_get(s_port0, s_pin1);
    else if (s2_id == num)
        return gpio_input_bit_get(s_port0, s_pin2);
    else if (s3_id == num)
        return gpio_input_bit_get(s_port1, s_pin3);
    else if (s4_id == num)
        return gpio_input_bit_get(s_port1, s_pin4);
    return s_id_null;
}
